const fs = require('fs');
var httpRequest = require('request');
var md5 = require('md5-node');
var redis = require('redis');
var redisClient = redis.createClient(6379,'localhost');
var app = require('express')();
var httpServer = require('http').Server(app);
const io = require('socket.io')(httpServer,{pingInterval:1000,upgradeTimeout:5000,pingTimeout:5000});
httpServer.setTimeout(1000);
httpServer.listen(3389, () => {
  console.log('listening on *:3389');
});
//const redis = require('socket.io-redis');
//io.adapter(redis({ host: 'localhost', port: 6379}));

console.log("任德龙の好字帖开始");

io.on('connection', socket => {
  var roomId = "";
  var userInfo = {avatar:"",nickname:"",gender:"",signature:"",role:"",roomId:"",lastSign:""};
  var statInfoKey = [];
  var retStatVal = {'redNum':0,'unionid':'','commentNum':0,'visitNum':0,'commentList':[],'padInfo':{}};

  console.log("connect one socket.(socket.id="+socket.id+")");
  setTimeout(function(){
      socket.emit('connection', "i");
  },1000);


  socket.on('write_stream',(msg)=> {
       console.log("pen-write:"+msg);
       socket.to(roomId).emit('write_stream',msg);

       var path = '/var/data/note/files/fontdata/'+roomId+".trace";
       fs.appendFile(path,msg, (error)  => {});
  });
 
  socket.on('write_ctrl',(msg)=> {
       console.log("write-ctrl:"+msg);
       socket.to(roomId).emit('write_ctrl',msg);

       var jjj = JSON.parse(msg);
       if(jjj[1][0] == 'clear'){
           clearTraceFile(); 
       }
       //var path = '/var/data/note/files/fontdata/'+roomId+".trace";
       //fs.appendFile(path,msg, (error)  => {});
  });
 
  function getPadRoleKey()
  {
      return roomId+"_NDPAD_USERINFO";
  }
  function getCommentListKey()
  {
      return roomId+"_commentList";
  }
  function savePadRole(){
      console.log("save_pad_role:");
      console.log(userInfo);
      redisClient.set(getPadRoleKey(), JSON.stringify(userInfo));
  }

  function sendStatRoomData(){
          statInfoKey = [];

	      //得到红心数
	      statInfoKey.push(roomId+'_redNum');
	      //得到评论数
	      statInfoKey.push(roomId+'_commentNum');
	      //得到浏览数
	      statInfoKey.push(roomId+'_visitNum');

          retStatVal['unionid'] = userInfo.signature;

          redisClient.mget(statInfoKey, function(err,val){
             val.forEach(function (oneV, i) {
                var keyArr = statInfoKey[i].split('_');
                var attrKey = keyArr.pop();
                 if(oneV){
                     retStatVal[attrKey] = parseInt(oneV);
                 }else{
                     retStatVal[attrKey] = 0;
                 }
             });

    	     //得到所有条评论
             var commentListKey = getCommentListKey();
             retStatVal["commentList"] = [];
             redisClient.send_command('lrange',[commentListKey, 0,-1], function(err, data){

          	    data.forEach(function (oneV, i) {
                    if(oneV){
                        var oneMsg = JSON.parse(oneV);
                        //console.log("\n--------------\noneMsg:");
                        //console.log(oneMsg);
                        retStatVal["commentList"].push(JSON.parse(oneV));
                    }
                });

                //console.log(roomId+">room sending StatRoomData>>");
                //console.log(retStatVal);
	            
                redisClient.get(getPadRoleKey(),function(err,jsonRaw){
                    var padInfo = JSON.parse(jsonRaw);
                    retStatVal['padInfo'] = padInfo;
                    socket.emit('stat-info', retStatVal);
                });
             });

 
          });
  }

  function clearTraceFile()
  {
       var path = '/var/data/note/files/fontdata/'+roomId+".trace";
       fs.truncate(path, 0, function(){
                            console.log('clear trace file:'+path);
       });
  }

  function dologinProc(userInfo)
  {
          console.log("dologinProc:"+roomId);
          console.log(userInfo);
          socket.join(roomId);
          socket.to(roomId).emit('someone-online', userInfo);

          sendStatRoomData();

          if(userInfo.role == "ND_PAD"){
              //如果是写者就上
              savePadRole();

              //清除笔记文件
              clearTraceFile();
          }

          addRoomVisitors();

          //增加用户信息缓存
          redisClient.set(userInfo.signature, JSON.stringify(userInfo));

          //增加浏览数量
          redisClient.incr(roomId+'_visitNum');

  }

  function doingLoginProc(userInfo)
  {
        if(userInfo.role == "ND_WX"){
             httpRequest('https://api.weixin.qq.com/sns/jscode2session?appid=wx8e23853fb3ef2cbc&secret=03e35a38772e13f04c439f009cc46384&js_code='+userInfo.signature+'&grant_type=authorization_code',
                function (error, response, body) {
                    console.log("doingLoginProc:");
                    console.log('https://api.weixin.qq.com/sns/jscode2session?appid=wx8e23853fb3ef2cbc&secret=03e35a38772e13f04c439f009cc46384&js_code='+userInfo.signature+'&grant_type=authorization_code');
                    if(!error && response.statusCode == 200){
                        var requestJson = JSON.parse(body);
                        if(requestJson.hasOwnProperty('openid') &&
                           requestJson.openid.length > 0
                        ){
                            console.log("got wx openid:"+requestJson.openid);
                            userInfo.signature = requestJson.openid;
                            dologinProc(userInfo);
                        }else{
                            console.log('得到 json 出错1'+body);
                            socket.emit('logout',body);
                            socket.disconnect()
                        }
                    }else{
                            console.log('得到 json 出错2');
                            console.log(response);
                            socket.emit('logout',response.statusCode);
                            socket.disconnect()
                    }
                }
             );
        }else{
            dologinProc(userInfo);
        }
  }

  socket.on('join-room',(msg)=> {
      console.log('join-room');
      console.log(msg);
      var joinRoomArr = msg.split("\r\n");
      console.log(joinRoomArr);
      if(joinRoomArr.length == 7){
	      var changeRoomId = joinRoomArr[0];
	      console.log('join-room:'+changeRoomId);
	   
          userInfo = {};
          userInfo.roomId = joinRoomArr[0];
          userInfo.role = joinRoomArr[1];
	      userInfo.avatar = joinRoomArr[2];
	      userInfo.nickname = joinRoomArr[3];
          userInfo.gender = joinRoomArr[4];
	      userInfo.signature = joinRoomArr[5];
	      userInfo.lastSign = joinRoomArr[6];

          if(userInfo.role == "ND_PAD" &&
             changeRoomId != roomId 
          ){
              socket.to(roomId).emit('change_page', userInfo);
          }

          roomId = changeRoomId;

          doingLoginProc(userInfo);
/*
	      socket.join(roomId);
          socket.to(roomId).emit('someone-online', userInfo);

          sendStatRoomData();

          if(userInfo.role == "ND_PAD"){
              //如果是写者就上
              savePadRole();
          }

          addRoomVisitors();

          //增加用户信息缓存
          redisClient.set(userInfo.signature, JSON.stringify(userInfo));

          //增加浏览数量
          redisClient.incr(roomId+'_visitNum');
*/     
      }

     
  });


  function getSharePic(token, md5,pagePath)
  {
        console.log('getSharePic pagePath:'+pagePath);
        console.log("getSharePic md5:"+md5);
             httpRequest({
                url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='+token,
                method: "POST",
                json: true,
                encoding: null,
                headers: {
                    "content-type": "application/octet-stream",
                },
                body:{
                       'scene' : md5,
                       'is_hyaline' : false,
                       'page' : pagePath,
                       'width' : 350,
                       'line_color':{"r":"255","g":"3","b":"9"}
                }
            }, function(error, response, body) {
                if (!error && response.statusCode == 200) {
                    var path = '/var/data/note/files/fontdata/'+md5+".png";
                    var url = 'https://wx.ndmooc.com/files/fontdata/'+md5+'.png';
                    //https://wx.ndmooc.com/files/fontdata/   /var/data/note/files/fontdata/
                    if(body.length){
                        fs.writeFile(path, body,(err)=>{
                        });
                    }
                    
                    console.log(body);
                    console.log('getSharePic was ok.pic length='+body.length);
                    console.log("getSharePic:"+path+"\t"+url);

                    socket.emit('share-code', url);
                }else{
                    socket.emit('share-code', '');
                }
            });
 
  };
 
  function shareCode(flag,msg){
      var pagePath = 'pages/ottShare/ottShare';
      if(flag == 'share-code-login'){
          pagePath = 'pages/ottLogin/ottLogin';
      }else if(flag == 'lottery-race'){
          pagePath = 'pages/ottLogin/lotteryRace';
          pagePath = 'pages/ottLogin/ottLogin';
      }

    console.log('shareCode:'+flag+"="+pagePath);

     var path = '/var/data/note/files/fontdata/'+msg+".png";
     fs.exists(path, function(exists) {
 	    if(exists){
            var url = 'https://wx.ndmooc.com/files/fontdata/'+msg+'.png';
            console.log('local have file:'+path+'  '+url);
            socket.emit('share-code', url);
        }else{
              redisClient.get('get-wx-access-token', function(err,data) {
                if(data == null){
                    httpRequest('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx8e23853fb3ef2cbc&secret=03e35a38772e13f04c439f009cc46384',
                        function (error, response, body) {
                            if (!error && response.statusCode == 200){
                                var requestJson = JSON.parse(body);
                                /*
                                { access_token:
           '37_2nKNyM7cfFLYi8zqXstXIXxM-nSXWn8i8IcPArtQOfhC76UYl_4SETBFsbEvWugEvunSFyI88zTLZDeAIAFTX',
          expires_in: 7200 }
                                */
                                requestJson.expires_in -= 200;
                                redisClient.set('get-wx-access-token', requestJson.access_token, function(err, obj) {
                                    console.log("getShareCode request:"+requestJson.access_token+"\texpire:"+requestJson.expires_in);
                                    redisClient.expire('get-wx-access-token', requestJson.expires_in);
                                    socket.emit('get-wx-access-token', requestJson.access_token);
                                });
        
                                getSharePic(requestJson.access_token, msg,pagePath);
                            }else{
                                socket.emit('share-code', '');
                            }
                        }
                  );
              }else{
                  console.log("get cache from redis by share-code");
                  getSharePic(data, msg,pagePath);
              }
            });

       }
     });
 
  }


  socket.on('share-code-login',(msg)=>{
      console.log('share-code-login:'+msg);
      shareCode('share-code-login', msg); 
  });


  socket.on('share-code',(msg)=>{
      console.log('share-code:'+msg);
      shareCode('share-code', msg); 
  });
  
  socket.on('lottery-race',(msg)=>{
      console.log('lottery-race:'+msg);
      shareCode('lottery-race', msg); 
  });


  function postAndCheckSpeak(msg,token)
  {
            httpRequest({
                url: 'https://api.weixin.qq.com/wxa/msg_sec_check?access_token='+token,
                method: "POST",
                json: true,
                headers: {
                    "content-type": "application/json",
                },
                body:{'content': msg.msgBody}
            }, function(error, response, body) {
                if (!error && response.statusCode == 200) {
                    if(body.errcode == 87014){
                        console.log("\n================\n"+msg.msgBody+"\n含有违法违规内容(°ー°〃)");
                        msg.msgBody = "含有违法违规内容";
                    }

                    var oneUserInfoMsg = userInfo;
                    oneUserInfoMsg['msg'] = msg;
                    saveOneComment(oneUserInfoMsg);
                }
            });
    
  }

  function sendToWxShanHu(msg)
  {
      redisClient.get('get-wx-access-token', function(err,data) {
        if(data == null){
            httpRequest('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx8e23853fb3ef2cbc&secret=03e35a38772e13f04c439f009cc46384',
                function (error, response, body) {
                    if (!error && response.statusCode == 200) {
                        var requestJson = JSON.parse(body);
                        /*
                        { access_token:
   '37_2nKNyM7cfFLYi8zqXstXIXxM-nSXWn8i8IcPArtQOfhC76UYl_4SETBFsbEvWugEvunSFyI88zTLZDeAIAFTX',
  expires_in: 7200 }
                        */

                        requestJson.expires_in -= 200;
                        redisClient.set('get-wx-access-token', requestJson.access_token, function(err, obj) {
                            console.log("sendToWxShanHu:"+requestJson.access_token+"\texpire:"+requestJson.expires_in);
                            redisClient.expire('get-wx-access-token', requestJson.expires_in);
                            socket.emit('get-wx-access-token', requestJson.access_token);
                        });

                        postAndCheckSpeak(msg, requestJson.access_token);
                    }
                }
          );
      }else{
          postAndCheckSpeak(msg, data);
      }
    });
  }

  socket.on('speaking', (msg) => {
      console.log("speaking:");
      console.log(msg);
      var oneUserInfoMsg = userInfo;
      oneUserInfoMsg['msg'] = msg;
      addRoomSpeaking();//增加一个说话的人
      //saveOneComment(oneUserInfoMsg);
      sendToWxShanHu(msg);
  });

  function getRoomVisitorsKey()
  {
    return roomId+'_visitors';
  }

  function addRoomVisitors(){
      redisClient.sadd(getRoomVisitorsKey(),userInfo.signature, function(err,data) {
            if(data == 0){
                //未来过
            }else{
                //来过
            }
      });
  };

  function addRoomSpeaking(){
      redisClient.sadd(roomId,userInfo.signature, function(err,data) {
            if(data == 0){
                //未发过言
            }else{
                //发过言
            }
      });
  };

  socket.on('room-visitors', (msg) => {
      redisClient.smembers(getRoomVisitorsKey(), function(err,data) {
           console.log("room-visitors by "+userInfo.nickname);
           console.log(data);
           if(data.length == 0){
               socket.emit('room-visitors', data);
           }else{
               var myPos = data.indexOf(userInfo.signature);
               if(myPos != -1){
                   console.log('room-visitors remove self-idx:'+myPos);
                   data.splice(myPos,1);
               }

               if(data.length == 0){
                    socket.emit('room-visitors', data);
               }

               redisClient.mget(data, function(err,data){
                   socket.emit('room-visitors', data);
               });
           }
      });
  });

  socket.on('room-commentators', (msg) => {
      redisClient.smembers(roomId, function(err,data) {
           console.log("room-commentators by "+userInfo.nickname);
           console.log(data);
           if(data.length == 0){
               socket.emit('room-commentators', data);
           }else{
               var myPos = data.indexOf(userInfo.signature);
               if(myPos != -1){
                   console.log('room-commentators remove self-idx:'+myPos);
                   data.splice(myPos,1);
               }

               if(data.length == 0){
                    socket.emit('room-commentators', data);
               }


               redisClient.mget(data, function(err,data){
                   socket.emit('room-commentators', data);
               });
           }
      });
  });

  function saveOneComment(oneUserInfoMsg){
      var commentListKey = getCommentListKey();
        if(oneUserInfoMsg.msg &&
            oneUserInfoMsg.msg.msgType
        ){
            if(oneUserInfoMsg.msg.msgType == "heart"){
               console.log("red heart num+1\r\nsending hearting❤");
               redisClient.incr(roomId+'_redNum');

                io.to(roomId).emit('someone-talking', oneUserInfoMsg);
               //var xx = setInterval(function(){ io.to(roomId).emit('someone-talking', oneUserInfoMsg); }, 200);
               //setTimeout(function(){ clearInterval(xx) }, 700);

            }else{
               console.log("comment num+1");
               redisClient.incr(roomId+'_commentNum');

               redisClient.send_command('LLEN',[commentListKey], function(err, data) {
          	      console.log("save one comment by id:"+data);
                   oneUserInfoMsg.msg.id = data+1;
                   redisClient.send_command('lpush',[commentListKey,JSON.stringify(oneUserInfoMsg)], function(err, data) {
                       console.log("save one comment:"+data);
                       console.log(oneUserInfoMsg);          //OK 
                       io.to(roomId).emit('someone-talking', oneUserInfoMsg);
         
         	      });
         
 	           });
            }
        }
 
  };

  socket.on('remove-talking', (msgId) => {
      msgId = parseInt(msgId);
      console.log("remove-talking: message id="+msgId);

       var commentListKey = getCommentListKey();
       redisClient.send_command('lrange',[commentListKey, 0,-1], function(err, data){
                var isCallback = false;
          	    data.forEach(function (oneV, i) {
                    if(oneV &&
                       !isCallback
                    ){
                        var oneMsg = JSON.parse(oneV);
                        console.log(oneMsg.msg.id+"=="+msgId+" && "+oneMsg.signature+"=="+userInfo.signature);
                        if(oneMsg.msg.id == msgId &&
                           oneMsg.signature == userInfo.signature
                        ){
                           console.log("\t"+oneMsg.msg.id+"=="+msgId+" && "+oneMsg.signature+"=="+userInfo.signature);
                           isCallback = true;
                            redisClient.send_command('Lrem',[commentListKey, 0, oneV], function(err, data){
                                console.log('moreve-talking callback: '+data);
                                socket.emit('remove-talking', msgId);
                            });

                            if(oneMsg.msg.msgType == "msg"){
                                console.log(roomId+'_commentNum -1');
                                redisClient.decr(roomId+'_commentNum');
                            }else if(oneMsg.msg.msgType == "heart"){
                               console.log(roomId+'_redNum -1');
                               redisClient.decr(roomId+'_redNum');
                            }
                        }
                    }
                });

                if(!isCallback){
                    socket.emit('remove-talking', '信息体错误，或者删除了别人的发言');
                }
       });
  });


  socket.on('disconnecting', () => {
      console.log("disconnecting-room:"+roomId)	;
  });

  socket.on('disconnect', () => {
     console.log("disconnect-room:"+roomId)	;
     socket.to(roomId).emit('someone-offline', userInfo);
  });

  socket.on('store-roomid', (msg) => {
     var key = md5(msg);
     console.log("store-roomid:"+key+"->"+msg);

     redisClient.set(key, msg);
     //redisClient.expire(key, 60*60*24*7);
     socket.emit('store-roomid', key);
  });

  socket.on('get-roomid', (msg) => {
     console.log("get-roomid:"+msg);

     redisClient.get(msg, function(err,data) {
         socket.emit('get-roomid', data);
     });
  });

  socket.on('get-wx-access-token', (msg) => {
     console.log('get-wx-access-token');
     redisClient.get('get-wx-access-token', function(err,data) {
        if(data == null){
            httpRequest('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx8e23853fb3ef2cbc&secret=03e35a38772e13f04c439f009cc46384',
                function (error, response, body) {
                    if (!error && response.statusCode == 200) {
                        var requestJson = JSON.parse(body);
                        /*
                        { access_token:
   '37_2nKNyM7cfFLYi8zqXstXIXxM-nSXWn8i8IcPArtQOfhC76UYl_4SETBFsbEvWugEvunSFyI88zTLZDeAIAFTX',
  expires_in: 7200 }
                        */

                        requestJson.expires_in -= 200;
                        redisClient.set('get-wx-access-token', requestJson.access_token, function(err, obj) {
                            console.log("http request accessToken:"+requestJson.access_token+"\texpire:"+requestJson.expires_in);
                            redisClient.expire('get-wx-access-token', requestJson.expires_in);
                            socket.emit('get-wx-access-token', requestJson.access_token);
                        });
                    }
                }
            );
        }else{
            console.log("redis cache accessToken:"+data);
            socket.emit('get-wx-access-token', data);
        }
     });

  });

});
